package ui;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dialog;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JTextField;
import javax.swing.border.LineBorder;

import org.joda.time.DateTime;
import org.joda.time.Days;
import org.joda.time.LocalDate;

import ui.CreateEditTaskDialog.TaskData;
import entity.general.MinTime;
import entity.main.Task;
import entity.main.Task.TaskType;
import entity.main.TimeTodayAlreadyZeroException;


public class ItemPanel2 extends JPanel implements ActionListener {

	public static interface TaskUpdatedListener
	{
		public void taskUpdated(ItemPanel2 ip2);

		public void taskDeleted(ItemPanel2 ip2, Task task);

		public void taskEdited(ItemPanel2 ip2, Task task, TaskData taskData);

		public void taskCompletedToggle(ItemPanel2 itemPanel2, Task task);
	}
	Set <TaskUpdatedListener> taskUpdatedListeners = new HashSet<>();
	
	private JTextField NameField;
	private JTextField spentTimeField;
	private JTextField timeToSpendField;
	private JPanel panel_1;
	private JPanel panel_2;
	private JButton AddMinute;
	private JButton AddFiveMinutes;
	private JButton AddTenMinutes;
	private JButton AddThirtyMinutes;
	private JButton AddHour;
	private JButton AddCustomTime;
	private JCheckBox PinCheckbox;

	Task task;
	private JPopupMenu popupMenu;
	private JPopupMenu DetailsPopupMenu;
//	private JMenuItem mntmDelete;
	private JPanel panel_3;
	private JPanel panel_4;
	private JMenuItem mntmComplete;
	private JMenuItem mntmEdit;
	private JMenuItem mntmDelete;
	private JLabel deadlineLabel;
	
	public ItemPanel2() {
		init();
	}
	
	public ItemPanel2(Task task) {
		this.task = task;
		init();
	}

	private void init()
	{
		setMinimumSize(new Dimension(476, 76));
		setMaximumSize(new Dimension(476, 76));
		setPreferredSize(new Dimension(476, 76));
		setBorder(new LineBorder(new Color(0, 0, 0), 1, true));
		
		popupMenu = new JPopupMenu();
		addPopup(this, popupMenu);
		
		mntmEdit = new JMenuItem("Edit");
		popupMenu.add(mntmEdit);
		
		mntmComplete = new JMenuItem("Complete");
		popupMenu.add(mntmComplete);
		
		mntmDelete = new JMenuItem("Delete");
		popupMenu.add(mntmDelete);
		
		ActionListener popupMenuListener = new ActionListener()
		{

			@Override
			public void actionPerformed(ActionEvent arg0) {
				if(arg0.getSource() == mntmEdit)
				{
//					CreateEditTaskDialog dialog = new CreateEditTaskDialog(task, new ArrayList <String>());
					
					//Todo - add categories
					List <String> l = new ArrayList <>();
					l.add("Other");
					CreateEditTaskDialog ctDialog = new CreateEditTaskDialog(task, l);
					ctDialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
					ctDialog.setVisible(true);
					ui.CreateEditTaskDialog.Status status = ctDialog.getStatus();
					System.out.println(ctDialog.getName() + ", " + status.name());
					
					if(status == status.OK)
					{
						String name = ctDialog.getName();
						TaskType type = ctDialog.getTaskType();
						String parentObjectiveName = ctDialog.getCategoryName();
						LocalDate start = DateTime.now().toLocalDate();
						LocalDate deadline;
						if(ctDialog.hasDeadline())
						{
							deadline = ctDialog.getDeadlineDate();
						}
						else
							deadline = null;
						String description = ctDialog.getDescription();
						MinTime timeToSpend = ctDialog.getTime();

						TaskData taskData;
						if(deadline == null)
						{
							taskData = new TaskData(name, description, timeToSpend, type, parentObjectiveName);
						}
						else
						{
							taskData = new TaskData(name, description, timeToSpend, type, parentObjectiveName, deadline);							
						}
						
						for(TaskUpdatedListener listener : taskUpdatedListeners)
						{
							listener.taskEdited(ItemPanel2.this, task, taskData);
						}
						//taskManagerBridge.createTask(name, type, parentObjectiveName, start, deadline, description, timeToSpend);
//						taskManagerBridge.createTask(name, type, parentObjectiveName, start, deadline, description, timeToSpend);
//						reloadDataFromTaskManagerBridge();
					}

					
				}
				else if(arg0.getSource() == mntmComplete)
				{
					for(TaskUpdatedListener listener : taskUpdatedListeners)
					{
						listener.taskCompletedToggle(ItemPanel2.this, task);
					}
				}
				else if(arg0.getSource() == mntmDelete)
				{
					int dialogResult = JOptionPane.showConfirmDialog (
						null, "Are you sure you want to delete this task? Deletion cannot be reversed!", "Really Delete?", JOptionPane.YES_NO_OPTION);

					if(JOptionPane.OK_OPTION == dialogResult)
					{
						System.out.println("Yes");
						for(TaskUpdatedListener listener : taskUpdatedListeners)
						{
							listener.taskDeleted(ItemPanel2.this, task);
						}
					}					
					else
					{
						System.out.println("No");						
					}					
				}
				else
				{
					throw new RuntimeException("Unknown menu option for source " + arg0.getSource() + ", " + arg0.getID());
				}
			}
			
		};
		mntmDelete.addActionListener(popupMenuListener);		
		mntmEdit.addActionListener(popupMenuListener);		
		mntmComplete.addActionListener(popupMenuListener);				
		
		GridBagLayout gridBagLayout = new GridBagLayout();
		gridBagLayout.columnWidths = new int[]{166, 0, 110, 39, 0};
		gridBagLayout.rowHeights = new int[] {66};
		gridBagLayout.columnWeights = new double[]{0.0, 1.0, 0.0, 0.0, Double.MIN_VALUE};
		gridBagLayout.rowWeights = new double[]{1.0};
		setLayout(gridBagLayout);
		
		NameField = new JTextField();
		if(task == null)
			NameField.setText("Test Text");
		else
			NameField.setText(task.getName());
		NameField.setEditable(false);
		GridBagConstraints gbc_NameField = new GridBagConstraints();
		gbc_NameField.fill = GridBagConstraints.HORIZONTAL;
		gbc_NameField.insets = new Insets(0, 0, 0, 5);
		gbc_NameField.gridx = 0;
		gbc_NameField.gridy = 0;
		add(NameField, gbc_NameField);
		NameField.setColumns(20);
		
		panel_3 = new JPanel();
		panel_3.setOpaque(false);
		GridBagConstraints gbc_panel_3 = new GridBagConstraints();
		gbc_panel_3.insets = new Insets(0, 0, 0, 5);
		gbc_panel_3.fill = GridBagConstraints.HORIZONTAL;
		gbc_panel_3.gridx = 1;
		gbc_panel_3.gridy = 0;
		add(panel_3, gbc_panel_3);
		GridBagLayout gbl_panel_3 = new GridBagLayout();
		gbl_panel_3.columnWidths = new int[]{138, 0};
		gbl_panel_3.rowHeights = new int[]{30, 0, 0, 0};
		gbl_panel_3.columnWeights = new double[]{1.0, Double.MIN_VALUE};
		gbl_panel_3.rowWeights = new double[]{0.0, 0.0, 1.0, Double.MIN_VALUE};
		panel_3.setLayout(gbl_panel_3);
								
		panel_4 = new JPanel();
		panel_4.setOpaque(false);
		GridBagConstraints gbc_panel_4 = new GridBagConstraints();
		gbc_panel_4.fill = GridBagConstraints.HORIZONTAL;
		gbc_panel_4.insets = new Insets(0, 0, 5, 0);
		gbc_panel_4.gridx = 0;
		gbc_panel_4.gridy = 0;
		panel_3.add(panel_4, gbc_panel_4);
		
		spentTimeField = new JTextField();
		panel_4.add(spentTimeField);
		spentTimeField.setColumns(5);
		spentTimeField.setText("00:00");
							
									
		JLabel BetweenLabel = new JLabel("of");
		panel_4.add(BetweenLabel);
		
		timeToSpendField = new JTextField();
		panel_4.add(timeToSpendField);
		timeToSpendField.setColumns(5);
		timeToSpendField.setText("00:00");
		
		deadlineLabel = new JLabel("No Deadline");
		GridBagConstraints gbc_deadlineLabel = new GridBagConstraints();
		gbc_deadlineLabel.insets = new Insets(0, 0, 5, 0);
		gbc_deadlineLabel.gridx = 0;
		gbc_deadlineLabel.gridy = 1;
		panel_3.add(deadlineLabel, gbc_deadlineLabel);
		
		JPanel panel = new JPanel();
		panel.setOpaque(false);
		GridBagConstraints gbc_panel = new GridBagConstraints();
		gbc_panel.anchor = GridBagConstraints.NORTHWEST;
		gbc_panel.insets = new Insets(0, 0, 0, 5);
		gbc_panel.gridx = 2;
		gbc_panel.gridy = 0;
		add(panel, gbc_panel);
		GridBagLayout gbl_panel = new GridBagLayout();
		gbl_panel.columnWidths = new int[]{0, 0};
		gbl_panel.rowHeights = new int[]{0, 0, 0};
		gbl_panel.columnWeights = new double[]{1.0, Double.MIN_VALUE};
		gbl_panel.rowWeights = new double[]{1.0, 1.0, Double.MIN_VALUE};
		panel.setLayout(gbl_panel);
		
		panel_1 = new JPanel();
		panel_1.setOpaque(false);
		GridBagConstraints gbc_panel_1 = new GridBagConstraints();
		gbc_panel_1.fill = GridBagConstraints.BOTH;
		gbc_panel_1.gridx = 0;
		gbc_panel_1.gridy = 0;
		panel.add(panel_1, gbc_panel_1);
		
		AddMinute = new JButton("1m");
		AddMinute.setPreferredSize(new Dimension(30, 23));
		AddMinute.setMargin(new Insets(2, 2, 2, 2));
		AddMinute.setMinimumSize(new Dimension(30, 23));
		AddMinute.setMaximumSize(new Dimension(30, 23));
		AddMinute.setFont(new Font("Tahoma", Font.PLAIN, 10));
		panel_1.add(AddMinute);
		
		AddFiveMinutes = new JButton("5m");
		AddFiveMinutes.setPreferredSize(new Dimension(30, 23));
		AddFiveMinutes.setMargin(new Insets(2, 2, 2, 2));
		AddFiveMinutes.setMinimumSize(new Dimension(30, 23));
		AddFiveMinutes.setMaximumSize(new Dimension(30, 23));
		AddFiveMinutes.setFont(new Font("Tahoma", Font.PLAIN, 10));
		panel_1.add(AddFiveMinutes);
		
		AddTenMinutes = new JButton("10m");
		AddTenMinutes.setPreferredSize(new Dimension(30, 23));
		AddTenMinutes.setMargin(new Insets(2, 2, 2, 2));
		AddTenMinutes.setMinimumSize(new Dimension(30, 23));
		AddTenMinutes.setMaximumSize(new Dimension(30, 23));
		AddTenMinutes.setFont(new Font("Tahoma", Font.PLAIN, 10));
		panel_1.add(AddTenMinutes);
		
		panel_2 = new JPanel();
		panel_2.setOpaque(false);
		GridBagConstraints gbc_panel_2 = new GridBagConstraints();
		gbc_panel_2.fill = GridBagConstraints.BOTH;
		gbc_panel_2.gridx = 0;
		gbc_panel_2.gridy = 1;
		panel.add(panel_2, gbc_panel_2);
		
		AddThirtyMinutes = new JButton("30m");
		AddThirtyMinutes.setPreferredSize(new Dimension(30, 23));
		AddThirtyMinutes.setMargin(new Insets(2, 2, 2, 2));
		AddThirtyMinutes.setMinimumSize(new Dimension(30, 23));
		AddThirtyMinutes.setMaximumSize(new Dimension(30, 23));
		AddThirtyMinutes.setFont(new Font("Tahoma", Font.PLAIN, 10));
		panel_2.add(AddThirtyMinutes);
		
		AddHour = new JButton("1h");
		AddHour.setPreferredSize(new Dimension(30, 23));
		AddHour.setMargin(new Insets(2, 2, 2, 2));
		AddHour.setMinimumSize(new Dimension(30, 23));
		AddHour.setMaximumSize(new Dimension(30, 23));
		AddHour.setFont(new Font("Tahoma", Font.PLAIN, 10));
		panel_2.add(AddHour);
		
		AddCustomTime = new JButton("xt");
		AddCustomTime.setPreferredSize(new Dimension(30, 23));
		AddCustomTime.setMargin(new Insets(2, 2, 2, 2));
		AddCustomTime.setMinimumSize(new Dimension(30, 23));
		AddCustomTime.setMaximumSize(new Dimension(30, 23));
		AddCustomTime.setFont(new Font("Tahoma", Font.PLAIN, 10));
		panel_2.add(AddCustomTime);
		
		AddMinute.addActionListener(this);
		AddFiveMinutes.addActionListener(this);
		AddTenMinutes.addActionListener(this);
		AddThirtyMinutes.addActionListener(this);
		AddHour.addActionListener(this);
		AddCustomTime.addActionListener(this);
		
		PinCheckbox = new JCheckBox("Pin");
		PinCheckbox.setOpaque(false);
		GridBagConstraints gbc_PinCheckbox = new GridBagConstraints();
		gbc_PinCheckbox.anchor = GridBagConstraints.WEST;
		gbc_PinCheckbox.gridx = 3;
		gbc_PinCheckbox.gridy = 0;
		add(PinCheckbox, gbc_PinCheckbox);
		PinCheckbox.addActionListener(this);
		
//		DetailsPopupMenu = new JPopupMenu();
//		add(DetailsPopupMenu);
//		
//		mntmDelete = new JMenuItem("Delete");
//		DetailsPopupMenu.add(mntmDelete);		
		
		if(task != null)
			setFieldsFromTask();
	}

	public void setFieldsFromTask()
	{
		if(task.isCompleted())
		{
			this.setBackground(Color.gray);
		}
		else if(task.getType() == TaskType.GOAL)
		{
			this.setBackground(new Color(100, 255, 100));
		}
		else if(task.getType() == TaskType.SINK)
		{
			this.setBackground(new Color(255, 150, 150));
		}
		else
		{
			throw new RuntimeException("Don't know this type " + task.getType().name());
		}
		
		if(task.isPinned())
		{
			PinCheckbox.setSelected(true);
		}
		else
		{
			PinCheckbox.setSelected(false);
		}

		if(task.getDeadline() != null)
		{
//			String daysLeft = Days.daysBetween(task.getDeadline(), DateTime.now().toLocalDate()).getDays() + "";
			String daysLeft = Days.daysBetween(DateTime.now().toLocalDate(), task.getDeadline()).getDays() + "";
			deadlineLabel.setText(task.getDeadline().toString() + " (" + daysLeft + " days)");
		}
		
		NameField.setText(task.getName());
		spentTimeField.setText(task.getTimeSpentOnTaskThisWeek().toString());
		timeToSpendField.setText(task.getTimePlanned().toString());
	}
	
	public Task getTask() {
		return task;
	}

	public void addTaskUpdatedListener(TaskUpdatedListener tuListener)
	{
		taskUpdatedListeners.add(tuListener);
	}
	
	@Override
	public void actionPerformed(ActionEvent arg0) {
		if(arg0.getSource() == AddMinute)
		{
			task.addTimeSpent(new MinTime(0, 1));
		}
		else if(arg0.getSource() == AddFiveMinutes)
		{
			task.addTimeSpent(new MinTime(0, 5));			
		}
		else if(arg0.getSource() == AddTenMinutes)
		{
			task.addTimeSpent(new MinTime(0, 10));			
		}
		else if(arg0.getSource() == AddThirtyMinutes)
		{
			task.addTimeSpent(new MinTime(0, 30));
		}
		else if(arg0.getSource() == AddHour)
		{
			task.addTimeSpent(new MinTime(1, 0));
		}
		else if(arg0.getSource() == AddCustomTime)
		{			
//			CreateEditTaskDialog ctDialog = new CreateEditTaskDialog(l);
//			ctDialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
//			ctDialog.setVisible(true);
//			Status status = ctDialog.getStatus();
//			System.out.println(ctDialog.getName() + ", " + status.name());

			AddSubTimeDialog tDialog = new AddSubTimeDialog();
			tDialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
			tDialog.setVisible(true);
			ui.AddSubTimeDialog.Status status = tDialog.getStatus();
			if(status == status.OK)
			{
				System.out.println("AddCustomTime pressed");
				if(tDialog.isAdd())
				{
					task.addTimeSpent(tDialog.getTime());
				}
				else
				{
					try
					{
						task.subTimeSpent(tDialog.getTime());					
					}
					catch(TimeTodayAlreadyZeroException ttaze)
					{
						//Warn
					}
				}
			}
			else
			{
				System.out.println("Status was " + status);
			}
		}
		else if(arg0.getSource() == PinCheckbox)
		{
			task.setPinned(PinCheckbox.isSelected());
		}
		
		for(TaskUpdatedListener tul : taskUpdatedListeners)
		{
			tul.taskUpdated(this);
		}
		setFieldsFromTask();
		invalidate();
	}

	private static void addPopup(Component component, final JPopupMenu popup) {
		component.addMouseListener(new MouseAdapter() {
			public void mousePressed(MouseEvent e) {
				if (e.isPopupTrigger()) {
					showMenu(e);
				}
			}
			public void mouseReleased(MouseEvent e) {
				if (e.isPopupTrigger()) {
					showMenu(e);
				}
			}
			private void showMenu(MouseEvent e) {
				popup.show(e.getComponent(), e.getX(), e.getY());
			}
		});
	}
}
